/*****************************************************************************
*
*  PROJECT:     SlipStream
*               (CGame - Game Header)
*  LICENSE:     GNU General Public License v3 - http://www.gnu.org/licenses/gpl.html

*  DEVELOPERS:  Philip Farquharson	<B00137077@studentmail.uws.ac.uk>
*				John Gray			<B00145524@studentmail.uws.ac.uk>		
*				Zohaib Bhatti		<B00104280@studentmail.uws.ac.uk>
*				Euan Hislop			<B00138636@studentmail.uws.ac.uk>
*
*****************************************************************************/

#ifndef CGAME
#define CGAME

#define _CRT_SECURE_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>								
#include <windowsx.h>
#include <gl\gl.h>								
#include <gl\glu.h>
#include <mmsystem.h>

//////ODE//////
#include <ode\ode.h>
#include <stdlib.h>
#include "OdeCubeObject\odeObject.h"
#include "OdeCubeObject\odeCube.h"
#include "timer.h"
//////////////

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

#include <cmath>
#define _USE_MATH_DEFINES	// Mathematical constant definitions
#include <cmath>

#include "CKeyBindManager.h"
#include "CTextureManager.h"
#include "CSkybox.h"
#include "CTimerManager.h"
#include "CVector3.h"
#include "CCamera.h"
#include "CSoundManager.h"
#include "CSound2D.h"
#include "CSound3D.h"
#include "MD5Model.h"
#include "CLighting.h"
#include "CThread.h"
#include "CLoader.h"
#include "reflections.h"
#include "CSkyBox.h"
#include "CParticleEmitter.h"
#include "CSingleton.h"
#include "CColor.h"
#include "CTextManager.h"

#include "bumpMapping.h"
#include "shadows.h"

#define DEFAULT_FPS_LIMIT				100

class CGame : public CSingleton < CGame >
{
public:
	static const int RESULT_EXIT_GAME = 0;
	static const int RESULT_CONTINUE_GAME = 1;

	// Camera collisions
	static const int zbound = 19;
	static const int zboundNeg = 164;
	static const int xbound = 88;
	static const int xboundNeg = 164;

	static int m_iReturnValue;

	CGame(){ m_iReturnValue = 1; };
	int init(HDC hDC);	
	int mainLoop();
	static void wKeyPressed();
	static void sKeyPressed();
	static void aKeyPressed();
	static void dKeyPressed();
	static void resetFullscreen();
	static void iKeyPressed();
	static void kKeyPressed();
	static void jKeyPressed();
	static void lKeyPressed();
	static void oKeyPressed();
	static void pKeyPressed();

	static void fourKeyPressed();
	static void fiveKeyPressed();
	static void sixKeyPressed();
	static void eightKeyPressed();

	void shutDown();
	void renderGLScene ( void );
	void resizeGLScene(GLsizei width, GLsizei height);

	static void Exit ()							{ m_iReturnValue = RESULT_EXIT_GAME; }

	static CKeyBindManager m_KeyBindManager;
	static CTextureManager m_TextureManager;
	static CTimerManager m_TimerManager;
	static CSoundManager m_SoundManager;
	static CCamera m_Camera;
	static CSkybox m_SkyBox;
	static MD5Model m_Player;
	static CLighting m_Lighting;
	static reflections m_Reflections;

	static CSound3D* m_pMusic;

	static shadows m_Shadows;
	static bumpMapping m_BumpMapping;

	// Fonts
	static GLuint fontBase;

	// Loading
	static CLoader* m_pLoader;
	static bool m_bLoaded;

	// Text on screen
	static CTextManager m_TextManager;
	static CTextObject* m_pTextFPS;
	static CTextObject* m_pTextPhysics;
	static CTextObject* m_pTextPhysicsCollisions;
	static CTextObject* m_pTextFullscreen;
	static CTextObject* m_pTextCameraPosition;
	static CTextObject* m_pTextControlsCamera;
	static CTextObject* m_pTextControlsShadows;
	static CTextObject* m_pTextControlsBumpmap;
	static CTextObject* m_pTextControlsPhysics;

	// Physics
	static dWorldID m_ODEWorld;
	static dSpaceID m_ODESpace;
	static dJointGroupID m_ODEJointGroup;
	static dGeomID m_floorPlane;
	static dGeomID m_roofPlane;
	static dGeomID m_wallPlaneNorth;
	static dGeomID m_wallPlaneEast;
	static dGeomID m_wallPlaneSouth;
	static dGeomID m_wallPlaneWest;
	static std::list<cOdeObject*>m_ObjList;
	typedef std::list<cOdeObject*>::iterator objIter;
	typedef std::list<cOdeObject*>::const_iterator constObjIter;
	static cTimer m_phyTimer;
	static int m_cCollisions;

	static void handleCollisions ( dGeomID obj0, dGeomID obj1 );
	static void nearCallback ( void* data, dGeomID obj0, dGeomID obj1 );
	static void updatePhysics ( );
	static void createBox ( void );

	// Textures
	CTexture *m_pTexMirror;

	// Threads
	CThread* m_pThreadModelLoader;
	static void* loadModels( void* );
	
	// FPS Variables
	static DWORD m_dwFPSLimit;
	static DWORD m_dwCurrentTime;
	static DWORD m_dwFPS;
	static DWORD m_dwLastFPS;
	static CTimer* tmrFPSLimiter;
	static void resetFPSCounter ( int iteration, int value );

	// Particle Emitters
	static CParticleEmitter *m_pParticleEmitter1;
	static CParticleEmitter *m_pParticleEmitter2;

	static unsigned int m_uiLoadTime;

	static HWND hWnd;
	static HDC hDC;
private:
	
	
};
#endif